#include "task.h"

LinkedList_TypeDef *head = NULL;


void LinkedList_AppendNode(TASK_InfoTypeDef info)
{
    LinkedList_TypeDef *node = head;

    if(head == NULL)
    {
        head = (LinkedList_TypeDef *)malloc(sizeof(LinkedList_TypeDef));

        if(head == NULL)
        {
            free(head);
        }
        else
        {
            memcpy(&head->info, &info, sizeof(TASK_InfoTypeDef));

            head->next = NULL;
        }
    }
    else
    {
        while(node->next != NULL)
        {
            node = node->next;
        }

        node->next = (LinkedList_TypeDef *)malloc(sizeof(LinkedList_TypeDef));

        if(node->next != NULL)
        {
            node = node->next;

            memcpy(&node->info, &info, sizeof(TASK_InfoTypeDef));

            node->next = NULL;
        }
        else
        {
            free(node->next);
        }
    }
}

uint8_t LinkedList_SearchNode(uint8_t index)
{
    LinkedList_TypeDef *node = head;

    while(node != NULL)
    {
        if(node->info.index == index)
        {
            return 1;
        }

        node = node->next;
    }

    return 0;
}


void Task_Append(uint8_t index, Task_Handler handler, uint32_t tick)
{
    TASK_InfoTypeDef info;

    info.index   = index;
    info.ready   = 0;
    info.tick    = tick;
    info.handler = handler;

    if(LinkedList_SearchNode(index) == 0)
    {
        LinkedList_AppendNode(info);
    }
}

void Task_TimeSlice(uint32_t tick)
{
    LinkedList_TypeDef *node = head;

    while(node != NULL)
    {
        if((tick % node->info.tick) == 0)
        {
            node->info.ready = 1;
        }
        
        node = node->next;
    }
}

void Task_Scheduling(void)
{
    LinkedList_TypeDef *node = head;

    while(node != NULL)
    {
        if(node->info.ready)
        {
            node->info.ready = 0;
            node->info.handler();
        }

        node = node->next;
    }
}



// void My_Task_Handler(void)
// {
//     printf("System Runing Time:%d s\r\n", g_iRunTimer/1000);
// }


void App_Task_Init(void)
{

// Task_Append(TASK_ID_MY, My_Task_Handler, 1000);

#if LED_ENABLE
	Task_Append(TASK_ID_LED, Led_Task_Handler, 2000); 	//添加LED闪烁任务，回调函数Led_Toggle，周期1000ms
#endif

#if BEEP_ENABLE
    Task_Append(TASK_ID_BEEP, Beep_Task_Handler, 500);
#endif
	
#if USART1_ENABLE
	Task_Append(TASK_ID_USART1_RECV, Usart1Recv_Task_Handler, 10); 	//添加串口1接收处理任务，回调函数Usart1Recv_Task_Handler，周期10ms
#endif
	
#if USART2_ENABLE
	Task_Append(TASK_ID_USART2_RECV, Usart2Recv_Task_Handler, 20); 	//添加串口2接收处理任务，回调函数Usart2Recv_Task_Handler，周期20ms
#endif

#if USART3_ENABLE
	Task_Append(TASK_ID_USART3_RECV, Usart3Recv_Task_Handler, 20); 	//添加串口3接收处理任务，回调函数Usart3Recv_Task_Handler，周期20ms
#endif

#if UART4_ENABLE
	Task_Append(TASK_ID_UART4_RECV, Uart4Recv_Task_Handler, 20); 	// 使用串口4来实现蓝牙的接收
#endif

#if UART5_ENABLE
	Task_Append(TASK_ID_UART5_RECV, Uart5Recv_Task_Handler, 20); 	//添加串口4接收处理任务，回调函数Uart4Recv_Task_Handler，周期20ms
#endif

#if ADC_ENABLE
    //PC4是模拟输入和PC5是太阳能输入
	Task_Append(TASK_ID_ADC, ADC_Task_Handler, 5000);
#endif

#if DAC_ENABLE
	Task_Append(TASK_ID_DAC, Dac_Task_Handler, 10); // 添加DAC任务，输出按模拟量正弦变化
#endif

#if BUTTON_ENABLE	
	Task_Append(TASK_ID_BUTTON, button_ticks, 5);//添加按键任务，回调函数button_ticks，周期5ms
#endif

#if TIMER4_CAPTURE_ENABLE
    //PB6用于输入捕获
	Task_Append(TASK_ID_TIMER4_RECV,Timer4_Capture_Task_Handler,1000); //添加输入捕获信息打印任务,3s周期，根据实际情况更改周期
#endif

#if XXX_ENABLE
    Task_Append(TASK_ID_INDEX,XXX_Task_Handler, tick);
	// 添加用户自定义任务，任务ID为TASK_ID_INDEX，回调函数XXX_Task_Handler，周期tick
#endif
}


